﻿using System.Runtime.InteropServices;
using System.Text;

namespace OpenCompiler.Scanning.Scanners
{
	public unsafe class CommentScanner : TokenScanner
	{
		private readonly char* _xmlComment;
		private readonly char* _adhocComment;
		private readonly char* _startComment;
		private readonly char* _endComment;

		public CommentScanner()
		{
			this._xmlComment = (char*)Marshal.StringToBSTR("///");
			this._adhocComment = (char*)Marshal.StringToBSTR("//");
			this._startComment = (char*)Marshal.StringToBSTR("/*");
			this._endComment = (char*)Marshal.StringToBSTR("*/");
		}

		public override bool IsToken(char* stringPointer, int remainingCharacters)
		{
			var adhoc = TokenHelper.IsMatch(stringPointer, remainingCharacters, this._adhocComment, 2);
			var start = TokenHelper.IsMatch(stringPointer, remainingCharacters, this._startComment, 2);
			if (adhoc || start)
			{
				return true;
			}
			return false;
		}

		public override bool CanSpanMultipleLines { get { return true; } }
		public override bool CanTokenBeSkipped { get { return false; } }

		public override object GetToken(ref char* stringPointer, int remainingCharacters)
		{
			var builder = new StringBuilder();
			if (TokenHelper.IsMatch(stringPointer, remainingCharacters, this._adhocComment, 2))
			{
				stringPointer += 2;
				remainingCharacters -= 2;
				for (; ; )
				{
					var currentCharacter = stringPointer[0];
					var EOL = TokenHelper.IsEOL(currentCharacter);
					if (remainingCharacters <= 0 || EOL)
					{
						break;
					}
					builder.Append(currentCharacter);

					stringPointer++;
					remainingCharacters--;
				}

			}
			else if (TokenHelper.IsMatch(stringPointer, remainingCharacters, this._startComment, 2))
			{
				stringPointer += 2;
				remainingCharacters -= 2;
				for( ;; )
				{
					var currentCharacter = stringPointer[0];
					if (remainingCharacters <= 1 || TokenHelper.IsMatch(stringPointer, remainingCharacters, this._endComment, 2))
					{
						break;
					}
					builder.Append(currentCharacter);
					stringPointer++;
					remainingCharacters--;
				}
				stringPointer += 2;
			}

			return builder.ToString();
		}

		
	}
}
